﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace EntityKit.Runtime
{
    /// <summary>
    /// 对象池管理器
    /// </summary>
    public static class ObjectPoolKit
    {
        /// <summary>
        /// 所有对象池
        /// </summary>
        private static Dictionary<string, GameObjectPool> GameObjectPools { get; set; } = new Dictionary<string, GameObjectPool>();

        
        
        /// <summary>
        /// 清空所有对象池
        /// </summary>
        public static void Release()
        {
            foreach (var pool in GameObjectPools)
            {
                pool.Value.Clear();
            }

            GameObjectPools.Clear();
        }
        
        
        /// <summary>
        /// 创建对象池
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <param name="spawnTem">对象模板</param>
        /// <param name="onSpawn">对象生成时初始化委托</param>
        /// <param name="onDespawn">对象回收时处理委托</param>
        /// <param name="limit">对象池上限，等于0时，表示使用默认值</param>
        public static void CreateGameObjectPool(string name, GameObject spawnTem, Action<GameObject> onSpawn = null, Action<GameObject> onDespawn = null, int limit = 100)
        {
            if (string.IsNullOrEmpty(name) || spawnTem == null)
                return;

            if (!GameObjectPools.ContainsKey(name))
            {
                GameObjectPools.Add(name, new GameObjectPool(spawnTem, limit, onSpawn, onDespawn));
            }
            else
            {
                Debug.LogError($"创建对象池失败：已存在对象池 {name} ！");
            }
        }

        /// <summary>
        /// 预加载对象池
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <param name="count">预加载数量</param>
        public static void PreloadGameObjectPool(string name, int count)
        {
            if (GameObjectPools.ContainsKey(name))
            {
                GameObjectPools[name].Preload(count);
            }
            else
            {
                Debug.LogError($"预加载对象池失败：不存在对象池 {name} ！");
            }
        }

        /// <summary>
        /// 清空指定的对象池
        /// </summary>
        /// <param name="name">对象池名称</param>
        public static void ClearGameObjectPool(string name)
        {
            if (GameObjectPools.ContainsKey(name))
            {
                GameObjectPools[name].Clear();
            }
            else
            {
                Debug.LogError($"清空对象池失败：不存在对象池 {name} ！");
            }
        }


        /// <summary>
        /// 删除对象池
        /// </summary>
        /// <param name="name">对象池名称</param>
        public static void DestroyGameObjectPool(string name)
        {
            if (GameObjectPools.ContainsKey(name))
            {
                GameObjectPools[name].Clear();
                GameObjectPools.Remove(name);
            }
            else
            {
                Debug.LogError($"移除对象池失败：不存在对象池 {name} ！");
            }
        }

        /// <summary>
        /// 是否存在指定名称的对象池
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <returns>是否存在</returns>
        public static bool IsExistGameObjectPool(string name)
        {
            return GameObjectPools.ContainsKey(name);
        }


        /// <summary>
        /// 获取对象池中对象数量
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <returns>对象数量</returns>
        public static int GetGameObjectPoolCount(string name)
        {
            if (GameObjectPools.TryGetValue(name, out var pool))
            {
                return pool.Count;
            }
            else
            {
                Debug.LogError($"获取对象数量失败：不存在对象池 {name} ！");
                return 0;
            }
        }

        /// <summary>
        /// 生成对象
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <returns>对象</returns>
        public static GameObject Spawn(string name)
        {
            if (GameObjectPools.ContainsKey(name))
            {
                return GameObjectPools[name].Spawn();
            }
            else
            {
                Debug.LogError($"生成对象失败：不存在对象池 {name} ！");
                return null;
            }
        }

        /// <summary>
        /// 回收对象
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <param name="target">对象</param>
        public static void Despawn(string name, GameObject target)
        {
            if (GameObjectPools.ContainsKey(name))
            {
                GameObjectPools[name].Despawn(target);
            }
            else
            {
                Debug.LogError($"回收对象失败：不存在对象池 {name} ！");
            }
        }

        /// <summary>
        /// 批量回收对象
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <param name="targets">对象数组</param>
        public static void Despawns(string name, GameObject[] targets)
        {
            if (targets == null)
                return;

            if (GameObjectPools.ContainsKey(name))
            {
                for (int i = 0; i < targets.Length; i++)
                {
                    GameObjectPools[name].Despawn(targets[i]);
                }
            }
            else
            {
                Debug.LogError($"回收对象失败：不存在对象池 {name} ！");
            }
        }

        /// <summary>
        /// 批量回收对象
        /// </summary>
        /// <param name="name">对象池名称</param>
        /// <param name="targets">对象集合</param>
        public static void Despawns(string name, List<GameObject> targets)
        {
            if (targets == null)
                return;

            if (GameObjectPools.ContainsKey(name))
            {
                for (int i = 0; i < targets.Count; i++)
                {
                    GameObjectPools[name].Despawn(targets[i]);
                }

                targets.Clear();
            }
            else
            {
                Debug.LogError($"回收对象失败：不存在对象池 {name} ！");
            }
        }
    }
}